package com.sophie.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * @author qiufen
 * @version 1.0
 * @date 2024-08-09 14:26
 */
public class DruidTool {

    private static DataSource dataSource;

    //当前线程关联的数据库对象
    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();

    static {
        try {
            Properties properties = new Properties();
            InputStream is =DruidTool.class.getClassLoader().getResourceAsStream("druid.properties");
            properties.load(is);
            //创建数据库连接池对象
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取连接对象
     *
     * @return
     */
    public static Connection getConnection() throws SQLException {
        //从线程中获取connection
        Connection conn = threadLocal.get();
        //如果conn为null,说明当前线程中没有连接对象
        if (conn == null) {
            //从阿里连接池中获取
            conn = dataSource.getConnection();
            //和当前线程绑定
            threadLocal.set(conn);
        }
        return conn;
    }

    public static void closeConn(Connection conn) throws SQLException {
        if (conn != null) {
            //和线程解绑
            threadLocal.remove();
            //如果开启了事务的手动提交，操作完毕后，归还给连接池之前，要将事务的自动提交改为true
            conn.setAutoCommit(true);
            //将Connection对象归还给连接池
            conn.close();
        }
    }

    public static void closeConn(Statement ps, Connection conn) throws SQLException {
        if (ps != null) {
            ps.close();
        }
        if (conn != null) {
            //和线程解绑
            threadLocal.remove();
            //如果开启了事务的手动提交，操作完毕后，归还给连接池之前，要将事务的自动提交改为true
            conn.setAutoCommit(true);
            //将Connection对象归还给连接池
            conn.close();
        }
    }

    public static void closeConn(ResultSet rs, Statement ps, Connection conn) throws SQLException {
        if (rs != null) {
            rs.close();
        }

        if (ps != null) {
            ps.close();
        }
        if (conn != null) {
            //和线程解绑
            threadLocal.remove();
            //如果开启了事务的手动提交，操作完毕后，归还给连接池之前，要将事务的自动提交改为true
            conn.setAutoCommit(true);
            //将Connection对象归还给连接池
            conn.close();
        }
    }

    /**
     * 开启事务
     */
    public static void startTransaction() throws SQLException {
        Connection conn = getConnection();
        //手动开启事务
        conn.setAutoCommit(false);
    }

    /**
     * 提交事务，并释放连接
     */
    public static void commitAndClose() throws SQLException {
        Connection conn = getConnection();
        //提交事务
        conn.commit();
        //如果开启了事务的手动提交，操作完毕后，归还给连接池之前，要将事务的自动提交改为true
        conn.setAutoCommit(true);
        //将Connection对象归还给连接池
        conn.close();
        //从线程中移除绑定
        threadLocal.remove();
    }

    /**
     * 事务回滚，并释放连接
     */
    public static void rollbackAndClose() throws SQLException {
        Connection conn = getConnection();
        //事务回滚
        conn.rollback();
        //如果开启了事务的手动提交，操作完毕后，归还给连接池之前，要将事务的自动提交改为true
        conn.setAutoCommit(true);
        //将Connection对象归还给连接池
        conn.close();
        //从线程中移除绑定
        threadLocal.remove();
    }

}
